package com.xmb.wpclient.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xmb.wpclient.config.DataBaseConfig;
import com.xmb.wpclient.constant.LayTableR;
import com.xmb.wpclient.constant.R;
import com.xmb.wpclient.entity.CashContrast;
import com.xmb.wpclient.entity.ItemContrast;
import com.xmb.wpclient.entity.VoucherUploadRecord;
import com.xmb.wpclient.service.ICashContrastService;
import com.xmb.wpclient.service.IItemContrastService;
import com.xmb.wpclient.service.ISysUserService;
import com.xmb.wpclient.service.IVoucherUploadRecordService;
import com.xmb.wpclient.utils.DateUtil;
import com.xmb.wpclient.utils.HttpRequestUtils;
import com.xmb.wpclient.utils.ShiroUtil;
import com.xmb.wpclient.vo.ResultVO;
import com.xmb.wpclient.vo.VoucherDetailVO;
import com.xmb.wpclient.vo.VoucherMasterVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

@Controller
@RequestMapping("/manage/voucher")
public class VoucherController {

    public static void main(String[] args) {
        System.out.println(new Date().getTime());
    }

    @Autowired
    private ICashContrastService iCashContrastService;

    @Autowired
    private IItemContrastService iItemContrastService;

    @Autowired
    private IVoucherUploadRecordService iVoucherUploadRecordService;

    @Value("${constant.companyCode}")
    private String companyCode;

    @Autowired
    private HttpRequestUtils httpRequestUtils;

    @Autowired
    private ISysUserService iSysUserService;

    @RequestMapping("/index")
    public String index(){
        return "voucher/index";
    }

    @RequestMapping("/upload_record")
    @ResponseBody
    public Object upload_record(String iyear, String iperiod){
        VoucherUploadRecord uploadRecord = iVoucherUploadRecordService.getOne(new LambdaQueryWrapper<VoucherUploadRecord>().eq(VoucherUploadRecord::getIyear, iyear)
                .eq(VoucherUploadRecord::getIperiod, iperiod));
        StringBuilder sb = new StringBuilder();
        if(uploadRecord == null){
            sb.append("上传状态：未上传");
        }else{
            sb.append("上传状态："+(uploadRecord.getStatus()?"已上传":"上传失败"));
            sb.append("，最近一次上传时间："+DateUtil.getDateTimeFormat(uploadRecord.getUploadTime()));
            if(!uploadRecord.getStatus()){
                sb.append("，失败原因："+uploadRecord.getMsg());
            }
        }
        return sb.toString();
    }

    @RequestMapping("/master_list")
    @ResponseBody
    public Object master_list(String iyear, String iperiod, String inoid) {
        List<VoucherMasterVO> list = getMasterList(iyear, iperiod, inoid);
        VoucherUploadRecord uploadRecord = iVoucherUploadRecordService.getOne(new LambdaQueryWrapper<VoucherUploadRecord>().eq(VoucherUploadRecord::getIyear, iyear)
                .eq(VoucherUploadRecord::getIperiod, iperiod));
        StringBuilder sb = new StringBuilder();
        if(uploadRecord == null){
            sb.append("上传状态：未上传");
        }else{
            sb.append("上传状态："+(uploadRecord.getStatus()?"已上传":"上传失败"));
            sb.append("，最近一次上传时间："+DateUtil.getDateTimeFormat(uploadRecord.getUploadTime()));
            if(!uploadRecord.getStatus()){
                sb.append("，失败原因："+uploadRecord.getMsg());
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("data", LayTableR.result(0, list.size(), list));
        result.put("msg", sb.toString());
        result.put("status", uploadRecord == null?false:uploadRecord.getStatus());
        return result;
    }

    @PostMapping("/detail_list")
    @ResponseBody
    public LayTableR detail_list(String iyear, String iperiod, String inoid) throws Exception {
        List<VoucherDetailVO> list = getDetailList(iyear, iperiod, inoid);
        return LayTableR.result(0, list.size(), list);
    }

    @PostMapping("/upload")
    @ResponseBody
    public R upload(String iyear, String iperiod) throws Exception {
        VoucherUploadRecord uploadRecord = iVoucherUploadRecordService.getOne(new LambdaQueryWrapper<VoucherUploadRecord>().eq(VoucherUploadRecord::getIyear, iyear)
                .eq(VoucherUploadRecord::getIperiod, iperiod));
        if(uploadRecord == null){
            uploadRecord = new VoucherUploadRecord();
            uploadRecord.setIyear(Integer.valueOf(iyear));
            uploadRecord.setIperiod(Integer.valueOf(iperiod));
        }
        /**上传凭证钱数据组装*/
        List<VoucherMasterVO> list = getMasterList(iyear, iperiod, "");
        for(VoucherMasterVO voucherMasterVO : list){
            voucherMasterVO.setCorpcode(companyCode);
            List<VoucherDetailVO> detaiList = getDetailList(iyear, iperiod, voucherMasterVO.getNo());
            for(VoucherDetailVO voucherDetailVO : detaiList){
                if(StringUtils.isNotEmpty(voucherDetailVO.getJobcode())){
                    ItemContrast itemContrast = iItemContrastService.getOne(new LambdaQueryWrapper<ItemContrast>().eq(ItemContrast::getItemCode, voucherDetailVO.getJobcode()));
                    if(itemContrast != null){
                        voucherDetailVO.setJobcode(itemContrast.getU8cItemCode());
                    }else{
                        voucherDetailVO.setJobcode(null);
                        voucherDetailVO.setOtherjobcode(voucherDetailVO.getJobcode());
                    }
                }
                if(StringUtils.isNotEmpty(voucherDetailVO.getCashflow())){
                    CashContrast cashContrast = iCashContrastService.getOne(new LambdaQueryWrapper<CashContrast>().eq(CashContrast::getCashCode, voucherDetailVO.getCashflow()));
                    if(cashContrast == null){
                        uploadRecord.setStatus(false);
                        uploadRecord.setMsg("凭证号："+voucherDetailVO.getNo()+"行号："+voucherDetailVO.getDetailindex()+"中的现金流量科目："+voucherDetailVO.getCashflow()+"未找到对应的U8C科目。");
                        uploadRecord.setUploadTime(new Date());
                        iVoucherUploadRecordService.saveOrUpdate(uploadRecord);
                        return R.error("凭证号："+voucherDetailVO.getNo()+"行号："+voucherDetailVO.getDetailindex()+"中的现金流量科目："+voucherDetailVO.getCashflow()+"未找到对应的U8C科目。");
                    }else{
                        voucherDetailVO.setCashflow(cashContrast.getU8cCashCode());
                    }
                }
            }
            voucherMasterVO.setDetails(detaiList);
        }
        /**凭证数据上传*/
        for(VoucherMasterVO voucherMasterVO : list){
            try {
                ResultVO vo = httpRequestUtils.httpRequest(JSON.toJSONString(voucherMasterVO));
                if(!vo.getCode().equals("200")){
                    uploadRecord.setStatus(false);
                    uploadRecord.setMsg("【上传异常】原因："+vo.getMsg());
                    uploadRecord.setUploadTime(new Date());
                    iVoucherUploadRecordService.saveOrUpdate(uploadRecord);
                    return R.error(vo.getMsg());
                }else{
                    if(vo.getData() != null){
                        Set<Map.Entry<String, String>> set = vo.getData().entrySet();
                        List<ItemContrast> itemContrastList = new ArrayList<>();
                        for(Map.Entry<String, String> entry : set){
                            ItemContrast itemContrast = new ItemContrast();
                            itemContrast.setItemCode(entry.getKey());
                            itemContrast.setU8cItemCode(entry.getValue());
                            itemContrastList.add(itemContrast);
                        }
                        iItemContrastService.saveBatch(itemContrastList);
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
                uploadRecord.setStatus(false);
                uploadRecord.setMsg("【上传异常】原因：接口异常");
                uploadRecord.setUploadTime(new Date());
                iVoucherUploadRecordService.saveOrUpdate(uploadRecord);
                return R.error("接口异常");
            }
        }
        uploadRecord.setStatus(true);
        uploadRecord.setMsg("");
        uploadRecord.setUploadTime(new Date());
        iVoucherUploadRecordService.saveOrUpdate(uploadRecord);
        return R.ok();
    }

    private List<VoucherMasterVO> getMasterList(String iyear, String iperiod, String inoid){
        List<VoucherMasterVO> list = new ArrayList<>();
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            String sql = "select dbill_date,ino_id,idoc,(select top 1 cdigest from Gl_Accvouch b where a.iyear=b.iyear and a.iperiod=b.iperiod and a.ino_id=b.ino_id order by inid) as cdigest,sum(md) as md,sum(mc) as mc,cbill,ccheck,daudit_date,cbook,iyear,iperiod " +
                    "from Gl_Accvouch a " +
                    "where iyear="+iyear+" and iperiod="+Integer.valueOf(iperiod)+(StringUtils.isNotEmpty(inoid)?" and inoid="+inoid : "")+
                    "group by dbill_date,ino_id,idoc,cbill,ccheck,daudit_date,cbook,iyear,iperiod "+
                    "order by ino_id";
            statement = DataBaseConfig.connection.createStatement();
            resultSet = statement.executeQuery(sql);
            while (resultSet.next()){
                VoucherMasterVO voucherMasterVO = new VoucherMasterVO();
                voucherMasterVO.setPrepareddate(DateUtil.getDateFormat1(resultSet.getObject("dbill_date").toString()));
                voucherMasterVO.setNo(resultSet.getObject("ino_id").toString());
                voucherMasterVO.setAttachment(resultSet.getObject("idoc").toString());
                voucherMasterVO.setExplanation(resultSet.getObject("cdigest").toString());
                voucherMasterVO.setMd(resultSet.getObject("md").toString());
                voucherMasterVO.setMc(resultSet.getObject("mc").toString());
                voucherMasterVO.setCbill(resultSet.getObject("cbill").toString());
                voucherMasterVO.setCcheck(resultSet.getObject("ccheck").toString());
                voucherMasterVO.setDauditdate(DateUtil.getDateFormat1(resultSet.getObject("daudit_date").toString()));
                voucherMasterVO.setCbook(resultSet.getObject("cbook").toString());
                voucherMasterVO.setIyear(resultSet.getObject("iyear").toString());
                voucherMasterVO.setIperiod(resultSet.getObject("iperiod").toString());
                list.add(voucherMasterVO);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(statement != null){
                    statement.close();
                }
                if(resultSet != null){
                    resultSet.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }

        }
        return list;
    }

    private List<VoucherDetailVO> getDetailList(String iyear, String iperiod, String inoid){
        List<VoucherDetailVO> list = new ArrayList<>();
        Statement statement = null;
        ResultSet resultSet = null;
        Statement itemStatement = null;
        ResultSet itemResultSet = null;
        Statement cashStatement = null;
        ResultSet cashResultSet = null;
        try {
            String sql = "select a.iyear,a.iperiod,a.ino_id,a.inid,a.md,a.mc,a.cdigest,a.ccode,a.cdept_id,b.cDepName,a.ccus_id,c.cCusName," +
                    "a.cperson_id,d.cPersonName,a.citem_id,a.citem_class,e.citem_name,e.ctable " +
                    "from Gl_Accvouch a left join Department b on a.cdept_id=b.cDepCode " +
                    "left join Customer c on a.ccus_id=c.ccuscode " +
                    "left join Person d on a.cperson_id=d.cPersonCode " +
                    "left join fitem e on a.citem_class=e.citem_class " +
                    "where a.iyear="+iyear+" and a.iperiod="+iperiod+" and a.ino_id="+inoid+" "+
                    "order by a.ino_id";
            statement = DataBaseConfig.connection.createStatement();
            resultSet = statement.executeQuery(sql);
            while (resultSet.next()){
                VoucherDetailVO voucherDetailVO = new VoucherDetailVO();
                voucherDetailVO.setIyear(resultSet.getObject("iyear").toString());
                voucherDetailVO.setIperiod(resultSet.getObject("iperiod").toString());
                voucherDetailVO.setNo(resultSet.getObject("ino_id").toString());
                voucherDetailVO.setDetailindex(resultSet.getObject("inid").toString());
                voucherDetailVO.setCreditamount(resultSet.getObject("mc").toString());
                voucherDetailVO.setDebitamount(resultSet.getObject("md").toString());
                voucherDetailVO.setExplanation(resultSet.getObject("cdigest").toString());
                voucherDetailVO.setAccsubj(resultSet.getObject("ccode").toString());
                voucherDetailVO.setDeptcode(resultSet.getObject("cdept_id")==null?"":resultSet.getObject("cdept_id").toString());
                voucherDetailVO.setDeptname(resultSet.getObject("cDepName")==null?"":resultSet.getObject("cDepName").toString());
                voucherDetailVO.setCustcode(resultSet.getObject("ccus_id")==null?"":resultSet.getObject("ccus_id").toString());
                voucherDetailVO.setCustname(resultSet.getObject("cCusName")==null?"":resultSet.getObject("cCusName").toString());
                voucherDetailVO.setPsncode(resultSet.getObject("cperson_id")==null?"":resultSet.getObject("cperson_id").toString());
                voucherDetailVO.setPsnname(resultSet.getObject("cPersonName")==null?"":resultSet.getObject("cPersonName").toString());
                if(resultSet.getObject("citem_id") != null){
                    String ctable = resultSet.getObject("ctable").toString();
                    String itemSql = "select citemcode,citemname from "+ctable+" where citemcode='"+resultSet.getObject("citem_id").toString()+"'";
                    itemStatement = DataBaseConfig.connection.createStatement();
                    itemResultSet = itemStatement.executeQuery(itemSql);
                    while (itemResultSet.next()){
                        voucherDetailVO.setJobcode(itemResultSet.getObject("citemcode").toString());
                        voucherDetailVO.setJobname(itemResultSet.getObject("citemname").toString());
                    }
                }
                String cashSql = "select cCashItem,md,mc from GL_CashTable where iyear="+iyear+" and iPeriod="+iperiod+" and iNo_id="+inoid+" and inid="+voucherDetailVO.getDetailindex();
                cashStatement = DataBaseConfig.connection.createStatement();
                cashResultSet = cashStatement.executeQuery(cashSql);
                while (cashResultSet.next()){
                    voucherDetailVO.setCashflow(cashResultSet.getObject("cCashItem").toString());
                    voucherDetailVO.setMoney(cashResultSet.getObject("md").toString().equals("0.0000")?cashResultSet.getObject("mc").toString():cashResultSet.getObject("md").toString());
                }
                list.add(voucherDetailVO);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(statement != null){
                    statement.close();
                }
                if(resultSet != null){
                    resultSet.close();
                }
                if(itemStatement != null){
                    itemStatement.close();
                }
                if(itemResultSet != null){
                    itemResultSet.close();
                }
                if(cashStatement != null){
                    cashStatement.close();
                }
                if(cashResultSet != null){
                    cashResultSet.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
        return list;
    }
}
